﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using lucky_dog_backend.Models;
using lucky_dog_backend.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace lucky_dog_backend.Controllers
{
    [Route("api/[controller]")]
    public class UsersController : Controller
    {
        private readonly UserService _userService;
        private readonly LuckyTableService _luckyTableService;
        private readonly IAuthenticateService _authService;
        private readonly ILogger<UsersController> _logger;

        public UsersController(ILogger<UsersController> logger, IAuthenticateService authService, UserService userService, LuckyTableService luckyTableService)
        {
            _userService = userService;
            _luckyTableService = luckyTableService;
            _authService = authService;
            _logger = logger;
        }

        // GET: api/<controller>
        [HttpGet]
        public async Task<ActionResult<AsyncDataFormat>> Get() =>
                    new AsyncDataSuccessWithData<List<UserDTO>>(
                        await UserListToDTO(await _userService.Get())
                        );

        // GET api/<controller>/5
        [HttpGet("{account}")]
        public async Task<ActionResult<AsyncDataFormat>> Get(string account)
        {
            var user = await _userService.GetAccount(account);
            if (user == null)
            {
                return new AsyncDataFaild("用户不存在");
            }
            return new AsyncDataSuccessWithData<UserDTO>(await UserToDTO(user));
        }

        [HttpGet("getUserWithToken/{token}")]
        [Authorize]
        public async Task<ActionResult<AsyncDataFormat>> GetUser(string token)
        {
            var tokenS = new JwtSecurityToken(token);
            object value;
            tokenS.Payload.TryGetValue("account", out value);
            UserDTO userDTO = await UserToDTO(
                await _userService.GetAccount(value.ToString())
            );
            if (userDTO == null)
            {
                return new AsyncDataFaild();
            }
            return new AsyncDataSuccessWithData<UserDTO>(userDTO);
        }
        [HttpPost]
        public async Task<ActionResult<AsyncDataFormat>> Create([FromBody] User user)
        {
            if (user.Account == null || user.Account == "") return new AsyncDataFaild("账户不能为空");
            var userData = await _userService.GetAccount(user.Account);
            if (userData != null) return new AsyncDataFaild("账户已存在");
            await _userService.Create(user);
            return new AsyncDataSuccessWithData<User>(await _userService.GetAccount(user.Account));
        }
        [HttpPost("login")]
        public async Task<ActionResult<AsyncDataFormat>> RequestToken([FromBody] LoginRequestDTO request)
        {
            _logger.LogInformation("login");
            string token;
            if (_authService.IsAuthenticated(request, out token))
            {
                var user = await _userService.GetAccount(request.Account);
                return new AsyncDataSuccessWithData<LoginResponseDTO>(new LoginResponseDTO(await UserToDTO(user), token));
            }
            return Ok(new AsyncDataFaild("帐号或密码错误"));
        }
        private async Task<List<UserDTO>> UserListToDTO(List<User> userList)
        {
            var tempList = new List<UserDTO>();
            foreach (var item in userList)
            {
                tempList.Add(await UserToDTO(item));
            }
            return tempList;
        }
        private async Task<UserDTO> UserToDTO(User user)
        {
            var luckyTables = await _luckyTableService.GetUserTable(user);
            var tempList = new List<TableInfo>();
            foreach (var item in luckyTables)
            {
                LuckyTableDTO table = LuckyTablesController.LuckyTableToDTO(item);
                tempList.Add(new TableInfo(table.Id, table.Title, table.DataCount));
            }
            return new UserDTO(user.Id, user.Account, user.Email, tempList);
        }
    }
}
